package uz.rt.dicom;

/**
 * Value multiplicity can be defines as the amount of fields that can be encoded inside a value field of a dicom
 * element. The number of variables encoded in a value field is variable. This value can be 1 or a number given by the
 * format 1-n.
 */
public class ValueMultiplicity implements Comparable<ValueMultiplicity>
{
// ------------------------------ FIELDS ------------------------------

    /** Minimum number of fields stored in the value field of a dicom element */
    private final int min;
    /** Maximum number of fields stored in the value field of a dicom element */
    private final int max;

// --------------------------- CONSTRUCTORS ---------------------------

    /**
     * Constructs a ValueMultiplicity object and initialises the minimum and maximum number of fields to an equal
     * number.
     *
     * @param value Number of fields stored inside a dicom element
     */
    public ValueMultiplicity(int value)
    {
        min = max = value;
    }

    /**
     * Creates a ValueMultiplicity object based on a string. The string should be formatted as described below:
     * <ul>
     * <li>one number</li>
     * <li>one number - second number</li>
     * </ul>
     *
     * @param s String storing the value multiplicity.
     */
    public ValueMultiplicity(String s)
    {
        if (!s.contains("-"))
        {
            this.min = Integer.valueOf(s);
            this.max = Integer.valueOf(s);
        } else
        {
            String[] sa = s.split("-");
            if (sa.length != 2) throw new RuntimeException(
                    "Parsing of the value multiplicty failed: required format is:" +
                            System.getProperty("line.separator") + "\tvalue" +
                            System.getProperty("line.separator") + "\tminValue - maxValue");
            min = Integer.valueOf(sa[0].trim());
            sa[1] = sa[1].trim();
            if (sa[1].endsWith("n"))
                max = Integer.MAX_VALUE;
            else
                max = Integer.valueOf(sa[1].trim());
        }
    }

    /**
     * Constructs a ValueMultiplicity object and initialises the minimum and maximum number of fields.
     *
     * @param min Minimum number of fields stored inside a dicom element
     * @param max Maximum number of fields stored inside a dicom element
     */
    public ValueMultiplicity(int min, int max)
    {
        this.min = min;
        this.max = max;
    }

    /**
     * Constructs a ValueMultiplicity object and initialises the minimum and maximum number of fields.
     *
     * @param min Minimum number of fields stored inside a dicom element
     * @param max Maximum number of fields stored inside a dicom element
     */
    public ValueMultiplicity(String min, String max)
    {
        this.min = Integer.valueOf(min);
        this.max = Integer.valueOf(max);
    }

// --------------------- GETTER / SETTER METHODS ---------------------

    /**
     * Get the maximum number of dicom fields in a dicom element.
     *
     * @return Maximum number of dicom fields in a dicom element.
     */
    public int getMax()
    {
        return max;
    }

    /**
     * Get the minimum number of dicom fields in a dicom element.
     *
     * @return Minimum number of dicom fields in a dicom element.
     */
    public int getMin()
    {
        return min;
    }

// ------------------------ CANONICAL METHODS ------------------------

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (!(o instanceof ValueMultiplicity)) return false;

        ValueMultiplicity that = (ValueMultiplicity) o;

        return max == that.max && min == that.min;
    }

    @Override
    public int hashCode()
    {
        int result = min;
        result = 31 * result + max;
        return result;
    }

    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        if (min == max)
            sb.append(min);
        else
            sb.append(min).append("-").append(max);
        return sb.toString();
    }

// ------------------------ INTERFACE METHODS ------------------------


// --------------------- Interface Comparable ---------------------

    public int compareTo(ValueMultiplicity o)
    {
        if (min != o.min) return Integer.compare(min, o.min);
        if (max != o.max) return Integer.compare(max, o.max);
        return 0;
    }
}
